from manim import *


'''
The difference between Transform and ReplacementTransform is that 
Transform(mob1, mob2) transforms the points (as well as other attributes like color) of mob1 
into the points/attributes of mob2.

ReplacementTransform(mob1, mob2) on the other hand literally 
replaces mob1 on the scene with mob2.
'''
class TwoTransforms(Scene):
    def construct(self):
        with open("log.txt", "w") as f:

            # 左边用于 Transform（保留同一对象）
            a1 = Circle(color=BLUE).shift(3*LEFT)
            b1 = Square(color=RED).shift(3*LEFT)
            c1 = Triangle(color=GREEN).shift(3*LEFT)

            # 右边用于 ReplacementTransform（替换对象）
            a2 = Circle(color=BLUE).shift(3*RIGHT)
            b2 = Square(color=RED).shift(3*RIGHT)
            c2 = Triangle(color=GREEN).shift(3*RIGHT)

            # 把初始对象加入场景
            self.add(a1, a2)

            def dump(label: str):
                # 打印当前 Scene.mobjects 概览 + 关注对象的 id 和是否在 scene 中
                print(f"=== {label} ===", file=f)
                print("Scene objects (type, id):", file=f)
                for m in self.mobjects:
                    print(" ", type(m).__name__, id(m), file=f)
                print("", file=f)
                print("Tracked vars:", file=f)
                print("  a1 -> id:", id(a1), "in_scene:", a1 in self.mobjects, file=f)
                print("  a2 -> id:", id(a2), "in_scene:", a2 in self.mobjects, file=f)
                print("  b2 -> id:", id(b2), "in_scene:", b2 in self.mobjects, file=f)
                print("  c2 -> id:", id(c2), "in_scene:", c2 in self.mobjects, file=f)
                print("", file=f)
                f.flush()

            # 初始状态
            dump("initial state")

            # 1) Transform（同一个对象被“变形”）
            self.play(Transform(a1, b1))
            dump("after Transform(a1, b1)")

            self.play(Transform(a1, c1))
            dump("after Transform(a1, c1)")

            # 2) ReplacementTransform（真正的替换：旧对象被移出、把新对象加到场景）
            self.play(ReplacementTransform(a2, b2))
            dump("after ReplacementTransform(a2, b2)")

            self.play(ReplacementTransform(b2, c2))
            dump("after ReplacementTransform(b2, c2)")

            # 最后淡出并记录最终状态
            self.play(FadeOut(a1), FadeOut(c2))
            dump("after FadeOuts (final)")
